#ifndef __WD_FUNC_H
#define __WD_FUNC_H
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <error.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/epoll.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <sys/uio.h>
#include <sys/sendfile.h>
#include <crypt.h>
#include <shadow.h>
#include<openssl/md5.h>

#define SIZE(a) (sizeof(a)/sizeof(a[0]))

typedef void (*sighandler_t)(int);

#define ARGS_CHECK(argc, num)   {\
    if(argc != num){\
        fprintf(stderr, "ARGS ERROR!\n");\
        return -1;\
    }}

#define ERROR_CHECK(ret, num, msg) {\
    if(ret == num) {\
        perror(msg);\
        return -1;\
    }}

#define THREAD_ERROR_CHECK(ret, func) {\
    if(ret != 0) {\
        fprintf(stderr, "%s:%s\n", func, strerror(ret));\
    }}

typedef enum {
    CMD_TYPE_PWD=1,
    CMD_TYPE_LS,
    CMD_TYPE_CD,
    CMD_TYPE_MKDIR,
    CMD_TYPE_RMDIR,
    CMD_TYPE_PUTS,
    CMD_TYPE_GETS,
    CMD_TYPE_TREE,
    CMD_TYPE_QUIT,
   CMD_TYPE_NOTCMD,  //不是命令

    CMD_TYPE_REGISTER1=100,
    CMD_TYPE_REGISTER1_ERROR,
    CMD_TYPE_REGISTER1_RIGHT,
    CMD_TYPE_REGISTER2,
    CMD_TYPE_REGISTER2_ERROR,
    CMD_TYPE_REGISTER2_RIGHT,

    CMD_TYPE_LOGIN1=200,
    CMD_TYPE_LOGIN1_ERROR,
    CMD_TYPE_LOGIN1_RIGHT,
    CMD_TYPE_LOGIN2,
    CMD_TYPE_LOGIN2_ERROR,
    CMD_TYPE_LOGIN2_RIGHT,

    //秒传技术
    CMD_TYPE_SECOND_TRANSMIT = 300,
    CMD_TYPE_NORMAL_TRANSMIT,

    //客户端下载文件
    CMD_TYPE_FILE_EXIST = 400,                                         
    CMD_TYPE_FILE_NOT_EXIST

}CmdType;

typedef struct
{
    int len;//记录内容长度
    CmdType type;
    char buff[1000];//记录内容本身
}train_t;

int transferFile(int sockfd);
int sendn(int sockfd, const void * buff, int len);
int recvn(int sockfd, void * buff, int len);

typedef struct task_s{
    int peerfd;
    train_t train;   
}client_task_t;
//表示由stdin输入到client端的命令参数

void user_register(int peerfd);
int register1(int peerfd,train_t *t);
void register2(int peerfd,train_t *t);

int login(int peerfd);
void login1(int peerfd,train_t *t);
void login2(int peerfd,train_t *t);
void showmenu(void);
void parseInput(char* input, char** args, char** content);
void doTask(client_task_t * task);
//每一个具体命令的执行
void cdCommand(client_task_t * task);
void lsCommand(client_task_t * task);
void pwdCommand(client_task_t * task);
void mkdirCommand(client_task_t * task);
void rmdirCommand(client_task_t * task);
void notCommand(client_task_t * task);
void putsCommand(client_task_t * task);
void getsCommand(client_task_t * task);
void treeCommand(client_task_t * task);
void quitCommand(client_task_t * task);
//断点续传
//获取MD5码
void getMD5(int fd, char* result);
#endif

